昨天簡單介紹了node-ffi-npi
的基本概念,今天要實際使用node-ffi-npi
來呼叫我們動態連結函庫內的函式。
首先安裝node-ffi-npi
:
pm install --save ffi-napi
``
在forge.config.js
新增擺放動態連結函庫及驅動程式的資料夾lib,打包時要一併加入:
extraResource": [
"build",
"lib"
,
``
接著修改main.js
,使用ffi-napi
模組:
onst ffi = require('ffi-napi')
``
宣告動態連結函庫SioSdk.dll
的路徑:
ar dllPath = path.join(__dirname, 'lib\\SioSdk.dll');
f (!isDev) {
dllPath = path.resolve(__dirname, '..\\lib\\SioSdk.dll');
``
由於開發階段的路徑與打包完成後的路徑會有區別,我們利用先前定義的`isDev`來判斷是否為開發階段,進而使用**不同的動態連結函庫路徑**。
使用ffi.Library
,將變數SioSdk
連結到SioSdk.dll
:
onst SioSdk = ffi.Library(dllPath, {
'Install': ['bool', []],
'Open': ['bool', []],
'Close': ['bool', []],
'GetCpuFanSpeed': ['uint', []]
);
``
如同[Day18](https://ithelp.ithome.com.tw/articles/10333653)及[Day19](https://ithelp.ithome.com.tw/articles/10334286)所介紹的標頭檔`SioSdk.h`,將安裝及移除驅動程式的函式和讀取CPU風扇轉速的函式根據`SioSdk.h`裡的**類型**及**參數**,宣告在變數`SioSdk`中。
依照先前Windows console app的流程,使用SioSdk
呼叫SioSdk.dll
中的函式來安裝驅動程式:
/ Install and open service
ar result = SioSdk.Install();
onsole.log(`Dev:${isDev}. Install service ${result}`);
esult = SioSdk.Open();
onsole.log(`Open service ${result}`);
``
然後在Electron應用程式結束時關閉並移除驅動程式:
pp.on('window-all-closed', () => {
result = SioSdk.Close();
if (process.platform !== 'darwin') {
app.quit()
}
)
``
將原本固定的測試值改為SioSdk.dll
中的GetCpuFanSpeed()
,回傳CPU風扇實際的轉速:
pcMain.handle('cpufan', () => GetCpuFanSpeed())
``
將lib資料夾複製到開發階段Electron應用程式執行的資料夾內:
copy lib .\node_modules\electron\dist\resources\lib /e /h /c /i
``
修改完成後,執行Electron應用程式,但卻會跳出這個錯誤訊息:
ref-napi
。且因為node-ffi-npi
使用了ref-napi
,所以才會產生上圖的錯誤訊息,其中一個解決方式是將Electron退回v21之前。輸入下列指令將Electron版本退回至v20.3.8:
pm install --save-dev electron@20.3.8
``
再次將lib資料夾複製到開發階段Electron應用程式執行的資料夾內,然後重新執行Electron應用程式,可以看到CPU風扇轉速數值顯示在Electron應用程式的UI上了,代表我們成功使用node-ffi-napi
呼叫SioSdk.dll
中的GetCPuFanSpeed()
函式讀取CPU風扇轉速。
在實際使用node-ffi-napi
連結動態連結函庫時,一直不斷跳出Uncaught Exception,起初還以為是遇到使用node-ffi-napi
的常見問題:
但再三確認相關程式碼後發現並不是以上的問題,在網路上爬了很多文後才了解到是Electron版本的問題,除了降版本以外,也有其他使用者修改了ffi-napi
跟ref-napi
,可以使用修改過後的版本避開這個問題,有興趣的可以到參考內容中查閱,這次Electron應用程式的原始碼也會放在我個人的repo供各位參考。
"Error in native callback" using ffi-napi in electron and electron-builder
Sio-App Repo